#include "light.h"

// 使用TIM3作为RGB控制的外设

// 1. 先初始化GPIO部分三个引脚
// 2. 配置TIM3的TimeBase部分
// 3. 配置AFIO, 将TIM3的输出通道改为`部分重映射`组
// 4. 配置TIM3的模式为PWM模式, 并设置好周期和占空比
// 5. 预装载功能
// 6. 开启定时器

void LIGHT_init(void)
{
    // GPIO
    // 配置时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    // 配置初始化结构体
    GPIO_InitTypeDef GPIO_initStruct = {0};
    // 开漏复用功能（Alternate Function Open-Drain）
    GPIO_initStruct.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_initStruct.GPIO_Pin = RGB_Pin_Red | RGB_Pin_Green | RGB_Pin_Blue;
    GPIO_initStruct.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(RGB_Port, &GPIO_initStruct);

    // TIM3
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    TIM_TimeBaseInitTypeDef TIM_tbInitStruct = {0};
    TIM_tbInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_tbInitStruct.TIM_Prescaler = 720 - 1; // 通常配置完后使其周期为1/10/100等值
    TIM_tbInitStruct.TIM_Period = 256 - 1; // 预载值
    TIM_TimeBaseInit(TIM3, &TIM_tbInitStruct);

    // TIM PWM
    TIM_OCInitTypeDef tim_ocInitStruct = {0};
    // 模式
    tim_ocInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    // 正向输出引脚开启(反向不用, 此定时器没有反向)
    tim_ocInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    // 比较值, 决定了占空比, 默认选0
    tim_ocInitStruct.TIM_Pulse = 0;
    // 极性取反, 刚好与灯的亮灭一致
    tim_ocInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
    // 对2通道使用此配置
    TIM_OC2Init(TIM3, &tim_ocInitStruct);
    // 对3通道使用此配置
    TIM_OC3Init(TIM3, &tim_ocInitStruct);
    // 对4通道使用此配置
    TIM_OC4Init(TIM3, &tim_ocInitStruct);

    // AFIO
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

    // 开启输出比较的预装载功能
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

    // 开启定时器
    TIM_Cmd(TIM3, ENABLE);
}

void LIGHT_setColor(uint8_t red, uint8_t green, uint8_t blue)
{
    // 通道2的输出比较值, 对应的就是红灯亮度
    TIM_SetCompare2(TIM3, red); 
    // 通道3的输出比较值, 对应的就是红灯亮度
    TIM_SetCompare3(TIM3, green); 
    // 通道4的输出比较值, 对应的就是红灯亮度
    TIM_SetCompare4(TIM3, blue); 
}
